



#ifndef _PDF_FONT_PARSER_TYPE1_H_
#define _PDF_FONT_PARSER_TYPE1_H_

#include <wx/arrstr.h>
#include <wx/string.h>
#include <wx/stream.h>

#if wxUSE_UNICODE

#include "wx/pdffontdatatype1.h"
#include "wx/pdffontdescription.h"
#include "wx/pdffontparser.h"

class wxPdfCffIndexArray;

/// Class representing a Type1 font parser
class WXDLLIMPEXP_PDFDOC wxPdfFontParserType1 : public wxPdfFontParser
{
public:
  /// Default constructor
  wxPdfFontParserType1();

  /// Default destructor
  virtual ~wxPdfFontParserType1();

  /// Identify font based on a font file
  
  wxPdfFontData* IdentifyFont(const wxString& fontFileName, int fontIndex);

  /// Parse font stream
  
  bool ParseFont(const wxString& fileName, wxInputStream* fontFile, wxInputStream* metricFile, bool onlyNames);

  /// Load the font data
  
  bool LoadFontData(wxPdfFontData* fontData);

  /// Read font metrics from Adobe Font Metric file
  
  bool ReadAFM(wxInputStream& afmFile);

  /// Read font metrics from Printer Font Metric file
  
  bool ReadPFM(wxInputStream& pfmFile);

  /// Read font data from font file
  
  bool ReadPFX(wxInputStream* pfxFile, bool onlyNames);

private:
  /// Convert Mac Type1 font file to PFB format
  wxMemoryOutputStream* ConvertMACtoPFB(wxInputStream* macFontStream);

  /// Check whether the font stream represents a Type1 font
  bool CheckType1Format(wxInputStream* stream, int& start, int& length);

  /// Check whether the stream represents font metric data in AFM format
  bool MetricIsAFM(wxInputStream* stream);

  /// Check whether the stream represents font metric data in PFM format
  bool MetricIsPFM(wxInputStream* stream);

  /// Identify a data block in a PFB font stream
  bool ReadPfbTag(wxInputStream* stream, unsigned char& blocktype, int& blocksize);

    void CheckRestrictions(long fsType);

    void SkipComment(wxInputStream* stream);

    void SkipSpaces(wxInputStream* stream);

    void SkipLiteralString(wxInputStream* stream);

    void SkipString(wxInputStream* stream);

    void SkipProcedure(wxInputStream* stream);

    void SkipArray(wxInputStream* stream);

    void SkipToNextToken(wxInputStream* stream);

  /// Get the next token from the font stream
  wxString GetToken(wxInputStream* stream);

  /// Get a literal string from the font stream
  wxString GetLiteralString(wxInputStream* stream);

  /// Get a value array from the font stream
  wxString GetArray(wxInputStream* stream);

  /// Parse a PostScript dictionary
  bool ParseDict(wxInputStream* stream, int start, int length, bool onlyNames);

  /// Check whether a character represents a valid hexadecimal digit 
  bool IsHexDigit(char digit);

    void DecodeHex(wxInputStream* inStream, wxOutputStream* outStream);

    void DecodeEExec(wxMemoryOutputStream* eexecStream, wxOutputStream* outStream, unsigned short seed, int lenIV);

  /// Get the private dictionary 
  bool GetPrivateDict(wxInputStream* stream, int start);

    void ParseFontMatrix(wxInputStream* stream);

    void ParseEncoding(wxInputStream* stream);

    void ParseSubrs(wxInputStream* stream);

    void ParseCharStrings(wxInputStream* stream);

    void ParsePrivate(wxInputStream* stream);

    void ReadBinary(wxInputStream& inStream, int start, int size, wxOutputStream& outStream);

  bool                         m_skipArray;            
  wxPdfFontDescription         m_fontDesc;             ///< font description
  wxPdfFontDataType1*          m_fontData;             ///< font data
  wxArrayString                m_encodingVector;       ///< encoding vector of the font
  wxPdfFontType1GlyphWidthMap* m_glyphWidthMap;        ///< map of glyph widths
  int                          m_missingWidth;         
  bool                         m_embedAllowed;         ///< Flag whether embedding is allowed
  bool                         m_subsetAllowed;        
  wxInputStream*               m_privateDict;          ///< Private dictionary stream
  bool                         m_isPFB;                ///< Flag whether the font data are in PFB format
  bool                         m_privateFound;         ///< Flag whether the private dictionary has been found
  bool                         m_fontDirAfterPrivate;  ///< Flag whether the font directory is located before or after the private dictionary
  wxString                     m_encoding;             ///< name of the encoding
  long                         m_lenIV;                
  wxPdfCffIndexArray*          m_charStringsIndex;     ///< charstring index
  wxPdfCffIndexArray*          m_subrsIndex;           ///< subroutine index
};

#endif 
#endif
